package cn.aopmin.service.impl;

import cn.aopmin.dao.BookMapper;
import cn.aopmin.domain.constant.RedisKeyTemplate;
import cn.aopmin.domain.entity.Book;
import cn.aopmin.event.LikedTaskEvent;
import cn.aopmin.handler.R;
import cn.aopmin.service.BookService;
import cn.aopmin.utils.JsonUtils;
import cn.aopmin.utils.RedisUtils;
import cn.aopmin.utils.UserContextHolder;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * service 实现类
 * @author 白豆五
 * @since 2025/3/12
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {

    @Override
    public R<String> likeTask(Long id) {
        try {
            log.info("begin into updated likeTask bookId=[{}]", id);
            Book entity = new Book();
            // 获取当前登录用户
            Long userId = UserContextHolder.getUserId();
            String key = RedisKeyTemplate.getKey(RedisKeyTemplate.BOOK_LIKED_SET, id);
            // 判断用户是否已经点赞,并更新数据库中的点赞数量
            Boolean member = RedisUtils.sIsMember(key, userId);
            BeanUtils.copyProperties(baseMapper.selectById(id), entity);
            entity.setLikedNum(entity.getLikedNum() + (member ? -1 : 1));
            if (log.isDebugEnabled()){
                log.info("end updated likeTask after result=[{}]", JsonUtils.toJsonString(entity));
            }
           this.updateById(entity);
        // 发布事件，操作Redis缓存
            Map<String, Object> params = new HashMap<>(1) {{
                put("id", id);
                put("userId", UserContextHolder.getUserId());
            }};
            SpringUtil.getApplicationContext().publishEvent(new LikedTaskEvent(this, params));
        } catch (Exception e) {
            log.error("updated likeTask error! reason={}", e);
            return R.error();
        }
        return R.success();
    }

}
/*
 Redis SET 代表无序集合 且 存储的元素是唯一的。
      操作命令:
            1、SADD key member1 [member2 …] ：向集合添加一个或多个成员。
            2、SREM key member1 [member2 …] ：移除集合中一个或多个成员。
            3、SMEMBERS key ：返回集合中的所有成员。
            4、SCARD key ：获取集合的长度。
            5、SINTER key1 [key2] ：返回给定所有集合的交集。
            6、SUNION key1 [key2] ：返回所有给定集合的并集。
            7、SDIFF key1 [key2] ：返回给定所有集合的差集。
 */